using System;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Test.BO.TestUtils;
using FireStarterModeller.Test;
using FireStarterModeller.Test.BO;
using NUnit.Framework;

namespace Firestarter.DB.Schema.Test.BO
{
    /// <summary>
    /// Provides a place to write custom tests for DBForeignKey objects.
    /// This file is only written once and can be changed.  The Def file
    /// attached to this as a dependent is rewritten with each regeneration
    /// and contains the standard tests for DBForeignKey.
    /// Regenerate this test project whenever there have been changes to the
    /// business objects.
    /// If tests are failing due to a unique setup in your application,
    /// you can either override the Create methods in TestUtils, or you
    /// can add the test to the ignore list below and reimplement it here.
    /// </summary>
    public partial class TestDBForeignKey
    {
        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DBForeignKey dbForeignKey = TestUtilsDBForeignKey.CreateUnsavedValidDBForeignKey();
            //---------------Assert Precondition----------------
            Assert.IsFalse(String.IsNullOrEmpty(dbForeignKey.ForeignKeyName), "Foreign Key Should not be null");
            //---------------Execute Test ----------------------
            string expectedToString = dbForeignKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dbForeignKey.ForeignKeyName, expectedToString);
        }

        [Test]
        public void TestGetForeignKeyColumnInfo_NullWhenNoColumnsExist()
        {
            //---------------Set up test pack-------------------
            DBForeignKey dbForeignKey = new DBForeignKey();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbForeignKey.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            string nonExistentColumn = GetRandomString();
            DBForeignKeyColumn dbForeignKeyColumn = dbForeignKey.GetForeignKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbForeignKeyColumn);
        }

        [Test]
        public void TestGetForeignKeyColumnInfo_NullIfNotFound()
        {
            //---------------Set up test pack-------------------
            DBForeignKey dbForeignKey = new DBForeignKey();

            DBForeignKeyColumn firstDBForeignKeyColumn = new DBForeignKeyColumn();
            firstDBForeignKeyColumn.ParentColumn = new DBColumn("TestColumn1");
            dbForeignKey.ForeignKeyColumns.Add(firstDBForeignKeyColumn);

            DBForeignKeyColumn secondDBForeignKeyColumn = new DBForeignKeyColumn();
            secondDBForeignKeyColumn.ParentColumn = new DBColumn("TestColumn2");
            dbForeignKey.ForeignKeyColumns.Add(secondDBForeignKeyColumn);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            DBForeignKeyColumn dbForeignKeyColumn = dbForeignKey.GetForeignKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbForeignKeyColumn);
        }

        [Test]
        public void TestGetForeignKeyColumnInfo_FindsExistingOne()
        {
            //---------------Set up test pack-------------------
            DBForeignKey dbForeignKey = new DBForeignKey();

            DBForeignKeyColumn firstDBForeignKeyColumn = new DBForeignKeyColumn();
            firstDBForeignKeyColumn.ParentColumn = new DBColumn("TestColumn1");
            dbForeignKey.ForeignKeyColumns.Add(firstDBForeignKeyColumn);

            DBForeignKeyColumn secondDBForeignKeyColumn = new DBForeignKeyColumn();
            const string columnName = "TestColumn2";
            secondDBForeignKeyColumn.ParentColumn = new DBColumn(columnName);
            dbForeignKey.ForeignKeyColumns.Add(secondDBForeignKeyColumn);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBForeignKeyColumn dbForeignKeyColumn = dbForeignKey.GetForeignKeyColumnInfo(columnName);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dbForeignKeyColumn);
        }

        [Test]
        public void Test_AddNullColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            try
            {
                key.AddColumnInfo(null, null);
                Assert.Fail("expected Err");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("parentColumn", ex.ParamName);
            }
        }

        [Test]
        public void Test_AddNullParentColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            try
            {
                key.AddColumnInfo(null, new DBColumn());
                Assert.Fail("expected Err");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("parentColumn", ex.ParamName);
            }
        }

        [Test]
        public void Test_AddNullRelatedColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            DBColumn dbColumn = new DBColumn();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBForeignKeyColumn keyColumn = key.AddColumnInfo(dbColumn, null);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, key.ForeignKeyColumns.Count);
            Assert.IsNotNull(keyColumn);
            Assert.AreSame(dbColumn, keyColumn.ParentColumn);
            Assert.IsNull(keyColumn.RelatedColumn);
        }

        [Test]
        public void Test_AddColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            DBColumn parentDBColumn = new DBColumn("TestColumn1");
            DBColumn relatedDBColumn = new DBColumn("TestRelatedColumnInfo");
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBForeignKeyColumn keyColumn = key.AddColumnInfo(parentDBColumn, relatedDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, key.ForeignKeyColumns.Count);
            Assert.IsNotNull(keyColumn);
            Assert.AreSame(parentDBColumn, keyColumn.ParentColumn);
            Assert.AreSame(relatedDBColumn, keyColumn.RelatedColumn);
        }

        [Test]
        public void Test_AddSecondColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            key.ForeignKeyColumns.Add(new DBForeignKeyColumn {ParentColumn = firstDBColumn});
            DBColumn seondDBColumn = new DBColumn("TestColumn2");
            DBColumn relatedDBColumn = new DBColumn("TestRelatedColumnInfo");

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBForeignKeyColumn keyColumn = key.AddColumnInfo(seondDBColumn, relatedDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, key.ForeignKeyColumns.Count);
            Assert.IsNotNull(keyColumn);
            Assert.AreSame(seondDBColumn, keyColumn.ParentColumn);
            Assert.AreSame(relatedDBColumn, keyColumn.RelatedColumn);
        }

        [Test]
        public void Test_AddColumnInfoTwice()
        {
            //---------------Set up test pack-------------------
            DBForeignKey key = new DBForeignKey();
            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            key.ForeignKeyColumns.Add(new DBForeignKeyColumn {ParentColumn = firstDBColumn});
            DBColumn relatedDBColumn = new DBColumn("TestRelatedColumnInfo");

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, key.ForeignKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBForeignKeyColumn keyColumn = key.AddColumnInfo(firstDBColumn, relatedDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, key.ForeignKeyColumns.Count);
            Assert.IsNotNull(keyColumn);
            Assert.AreSame(firstDBColumn, keyColumn.ParentColumn);
        }

        [Test]
        public void Test_RelatedTableName_WhenTableNull_ShouldRetEmptyString()
        {
            //---------------Set up test pack-------------------
            DBForeignKey pkTable = new DBForeignKey();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(pkTable);
            Assert.IsNull(pkTable.RelatedTable);
            //---------------Execute Test ----------------------
            string tableName = pkTable.RelatedTableName;
            //---------------Test Result -----------------------
            Assert.IsEmpty(tableName);
        }

        [Test]
        public void Test_RelatedTableName_WhenTableNotNull_ShouldRetDBTableName()
        {
            //---------------Set up test pack-------------------
            var pkTable = new DBForeignKey();
            string expectedTableName = GetRandomString();
            pkTable.RelatedTable = new DBTable(expectedTableName);
            //---------------Assert Precondition----------------
            Assert.IsNotNull(pkTable);
            Assert.IsNotNull(pkTable.RelatedTable);
            Assert.IsNotNullOrEmpty(pkTable.RelatedTable.TableName);
            //---------------Execute Test ----------------------
            string tableName = pkTable.RelatedTableName;
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedTableName, tableName);
        }

        private static string GetRandomString()
        {
            return TestUtilsShared.GetRandomString();
        }
    }
}